package com.dreams.dream.common.async.disruptor;

public class DomainMessage {

    protected Object eventSource;

    protected volatile EventResultHandler eventResultHandler;

    protected volatile Object eventResult;

    public DomainMessage(Object eventSource) {
        super();
        this.eventSource = eventSource;
        // default is EventResultHandlerImp
        this.eventResultHandler = new EventResultHandlerImp();
    }

    public Object getEventSource() {
        return eventSource;
    }

    public EventResultHandler getEventResultHandler() {
        return eventResultHandler;
    }

    public void setEventResultHandler(EventResultHandler eventResultHandler) {
        this.eventResultHandler = eventResultHandler;
    }

    /**
     * setup time out(MILLISECONDS) value for get a Event Result
     * 
     * @param timeoutforeturnResult
     *            MILLISECONDS
     */
    public void setTimeoutforeturnResult(int timeoutforeturnResult) {
        if (eventResultHandler != null)
            eventResultHandler.setWaitforTimeout(timeoutforeturnResult);
    }

    /**
     * get a Event Result until time out value
     * 
     * @return Event Result
     */
    public Object getEventResult() {
        if (eventResult == null) {
            synchronized (this) {
                if (eventResultHandler != null) {
                    eventResult = eventResultHandler.get();
                    if (this.eventResultHandler != null) {
                        this.eventResultHandler.clear();
                        this.eventResultHandler = null;
                    }
                }
            }
        }
        return this.eventResult;
    }

    /**
     * * Blocking until get a Event Result
     * 
     * @return
     */
    public Object getBlockEventResult() {
        if (eventResult == null) {
            synchronized (this) {
                if (eventResultHandler != null) {
                    eventResult = eventResultHandler.getBlockedValue();
                    if (this.eventResultHandler != null) {
                        eventResultHandler.clear();
                        this.eventResultHandler = null;
                    }
                }
            }
        }
        return this.eventResult;
    }

    public void setEventResult(Object eventResultValue) {
        if (eventResultHandler != null) {
            eventResultHandler.send(eventResultValue);
        }
    }

    public void setEventSource(Object eventSource) {
        this.eventSource = eventSource;
    }

    public void clear() {
        this.eventResult = null;
        this.eventResultHandler = null;
        this.eventSource = null;
    }

    public boolean isNull() {
        if (this.eventResultHandler == null)
            return true;
        else
            return false;
    }

}
